package com.example.myunisdkdemo.util;

import android.content.Context;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * DownloadUtil是一个工具类，用于通过HTTP下载文件并将其保存到设备的外部存储中。
 * <p>
 * 该类使用OkHttp库来处理文件下载。它提供了异步下载文件的方法，并通过回调接口
 * 实时提供下载进度和结果。
 * </p>
 */
public class DownloadUtil {
    private static DownloadUtil downloadUtil;
    private final OkHttpClient okHttpClient;
    private Context context;
    private final String TAG = "下载页面";

    /**
     * 获取DownloadUtil的单例实例
     *
     * @return DownloadUtil实例
     */
    public static DownloadUtil get() {
        if (downloadUtil == null) {
            downloadUtil = new DownloadUtil();
        }
        return downloadUtil;
    }

    /**
     * 私有构造函数，防止外部直接实例化
     */
    private DownloadUtil() {
        okHttpClient = new OkHttpClient();
    }

    /**
     * 下载文件
     *
     * @param context    上下文，以便获取外部存储目录
     * @param url       文件的下载链接
     * @param saveDir   文件保存的目录名
     * @param fileName  保存后的文件名
     * @param listener   下载进度和结果的回调接口
     */
    public void download(Context context, final String url, final String saveDir, final String fileName, final OnDownloadListener listener) {
        this.context = context;
        // 创建请求对象
        Request request = new Request.Builder().url(url).build();

        // 异步执行下载请求
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 下载失败，调用回调方法
                listener.onDownloadFailed();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len;
                FileOutputStream fos = null;

                // 创建或检查目录
                File directory = new File(context.getExternalFilesDir(null), saveDir);
                if (!directory.exists()) {
                    directory.mkdirs(); // 创建目录
                }

                // 创建保存文件对象
                File file = new File(directory, fileName);

                // 如果文件已存在，则删除它
                if (file.exists()) {
                    file.delete();
                }

                try {
                    // 获取输入流和文件输出流
                    is = response.body().byteStream();
                    long total = response.body().contentLength();
                    fos = new FileOutputStream(file);
                    long sum = 0;

                    // 循环读取输入流，写入到文件
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        int progress = (int) (sum * 1.0f / total * 100);
                        // 更新下载进度
                        listener.onDownloading(progress);
                    }
                    fos.flush();
                    // 下载完成，调用成功回调
                    listener.onDownloadSuccess(file);
                } catch (Exception e) {
                    // 处理异常并调用失败回调
                    listener.onDownloadFailed();
                } finally {
                    // 关闭流
                    try {
                        if (is != null) is.close();
                        if (fos != null) fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    /**
     * 下载状态回调接口
     */
    public interface OnDownloadListener {
        /**
         * 下载成功的回调
         *
         * @param file 下载成功的文件
         */
        void onDownloadSuccess(File file);

        /**
         * 下载进度回调
         *
         * @param progress 当前的下载进度（百分比）
         */
        void onDownloading(int progress);

        /**
         * 下载失败的回调
         */
        void onDownloadFailed();
    }
}